<style lang="scss">
  .tab {
		.tab-box{
			height: 130rpx;
		}
    &-list {
      position: relative;
      display: flex;
      width: 100%;
      padding: 20rpx 0 0;
			align-items: flex-end;
      &-line {
        position: absolute;
        bottom: -6rpx;
        left: 0;
        height: 8rpx;
        border-radius: 4rpx;
        background: #6175F4;
      }
    }
    &-item {
      flex: 1;
      padding: 14rpx 0 16rpx;
      text-align: center;
      font-size: 30rpx;
    }
  }
</style>

<template>
  <view class="tab">
    <view class="tab-box">
    	<view
    	  class="tab-list" 
    	  :class="className" 
    	  id="tabList" 
    	  @click="changeTab($event)" 
    	  :active="active"
    	  :style="{
    	    top: fixed ? top + 'px' : 0,
    	    position: fixed ? 'fixed' : 'relative',
    	    zIndex: fixed ? 99 : 1,
    	    borderBottom: borderShow ? '1px solid #F2F2F2' : 'none',
    	    paddingBottom: borderShow ? '10rpx;' : '0',
    	    backgroundColor: bgColor}">
    	  <view
    	    v-for="(item, index) in tabs" 
    	    class="tab-item"
    	    :key="index"
    	    :data-name="item.name || index"
    	    :style="{
						color: currentIndex == index ? textActiveColor : textInActiveColor,
						fontWeight: currentIndex == index ? 'bold' : '',
						fontSize: borderShow ? '36rpx' : currentIndex == index ? '36rpx' : '30rpx',
					}"
    	    :class="itemClassName">{{item.title}}</view>
    	  <view 
    	    class="tab-list-line" 
    	    :style="{
    	      width: lineWidth + 'rpx',
    	      transform: transformStr,
    	      'background-color': lineColor, 
    	      'bottom':borderShow ? '8rpx' : '-6rpx',
    	      'transition-duration': '0.3s'}"></view>
    	</view>
    </view>
    <view class="tab-content">
      <slot></slot>
    </view>
  </view>
</template>

<script>
  export default {
    name: 'tab',
    model: {
      prop: 'value'
    },
    props: {
      bgColor: {
        type: String, 
        default: '#ffffff'
      },
      textInActiveColor: {
        type: String,
        default: '#98A1B5'
      },
      textActiveColor: {
        type: String,
        default: '#333'
      },
      lineColor: {
        type: String,
        default: '#6175F4'
      },
      className: {
        type: String, 
        default: ''
      },
      itemClassName: {
        type: String, 
        default: ''
      },
      value: {
        type: [Number, String],
        default: 0
      },
      fixed: {                                    // 是否将tab固定在顶部
        type: Boolean,
        default: false
      },
      lineWidth: {
        type: Number,
        default: 40
      },
      top: {
        type: Number,
        default: 0
      },
      borderShow: {
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        tabWidth: 0,
        tabs: [],
        currentIndex: null               // 当前选中tab的索引
      }
    },
    watch: {
      value(name) {
        if (name !== this.currentName) {
          this.setCurrentIndexByName(name);
        }
      }
    },
    mounted() {
      // 获取子节点
      this.tabs = this.$children.map((v, index) => {
        v.index = index
        return {
          title: v.title,
          name: v.name
        }
      })
      this.$nextTick(() => {
        this.getTabWidth()
        this.setCurrentIndexByName(this.currentName || this.value)
      })
    },
    computed: {
      transformStr() {
        // 计算tab的下划线的位置
        let tabNum = this.tabs.length
        let initTransformLeft = this.tabWidth / tabNum / 2
        let tabItemWidth = this.tabWidth / tabNum
        
        return `translateX(${initTransformLeft + (this.currentIndex) * tabItemWidth}px) translateX(-50%)`
      },
      currentName() {
        // 根据索引获取当前选中pane的name
        var activeTab = this.$children[this.currentIndex];

        if (activeTab) {
          return activeTab.computedName;
        }
      }
    },
    methods: {
      // 获取tab的宽度
      getTabWidth() {
        const query = uni.createSelectorQuery().in(this);
        query.select('#tabList').boundingClientRect((data) => {
          this.tabWidth = data.width
        }).exec();
      },
      // 切换tab     
      changeTab(e) {
        if(e.target.dataset.name == 0 || e.target.dataset.name) {
          this.setCurrentIndexByName(e.target.dataset.name, true)
        }
      },
      // 根据选项卡name获取选项卡索引
      setCurrentIndexByName(name, checked) {
        var matched = this.$children.find((tab) => {
          return tab.computedName === name;
        })

        // 若在children中未找到匹配的，则默认为第一个选项卡
        var defaultIndex = (this.$children[0] || {}).index || 0;
        this.setCurrentIndex(matched ? matched.index : defaultIndex, checked);
      },
      // 设置索引
      setCurrentIndex(currentIndex, checked) {
        this.currentIndex = currentIndex;
        this.$emit('input', this.currentName);
        if(checked) {
          this.$emit('change', this.currentName, this.$children[currentIndex].title);
        }
      }
    }
  }
</script>
